// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.expand.service.impl;

import com.liuxinlong.common.*;
import com.liuxinlong.enums.InventoryStatusEnum;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.dao.InventoryDao;
import com.liuxinlong.modules.entity.Inventory;
import com.liuxinlong.modules.expand.service.InventoryService;
import com.liuxinlong.utils.ExcelUtils;
import com.liuxinlong.utils.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 库存管理service实现
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022年5月20日
 */
@Service
@Slf4j
public class InventoryServiceImpl implements InventoryService {

    @Autowired
    private InventoryDao inventoryDao;

    @Autowired
    private ExcelImportService excelImportService;

    @Override
    public List<Map<String, Object>> pageInventoryList(Map<String, Object> queryParam) {
        List<Inventory> originList = inventoryDao.pageInventoryList(queryParam);
        List<Map<String, Object>> resultList = new ArrayList<>(originList.size());
        int sort = (int) queryParam.get("startNum") + 1;
        for (Inventory inventory : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(inventory);
            map.put("sort", sort);
            resultList.add(map);
            sort++;
        }
        return resultList;
    }

    @Override
    public int getInventoryCount(Map<String, Object> queryParam) {
        return inventoryDao.getInventoryCount(queryParam);
    }

    @Override
    public void addInventory(Inventory inventory) {
        Inventory oldInventory = inventoryDao.selectOneByParam(inventory.getSn(),
                inventory.getPurchaseTime().substring(0,10));
        if (!ObjectUtils.isEmpty(oldInventory)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "已存在相同库存记录");
        }
        inventory.setId(SnowFlake.nextIdStr());
        inventory.setStatus(InventoryStatusEnum.NORMAL.getValue());
        inventoryDao.addInventory(inventory);
    }

    @Override
    public void updateInventory(Inventory inventory) {
        Inventory dbInfo = inventoryDao.selectById(inventory.getId());
        if (ObjectUtils.isEmpty(dbInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改失败，库存记录不存在");
        }
        if (inventory.getLeftNumber() == 0) {
            inventory.setStatus(InventoryStatusEnum.PROCESSED.getValue());
        } else {
            inventory.setStatus(dbInfo.getStatus());
        }
        inventoryDao.updateInventory(inventory);
    }

    @Override
    public void deleteInventory(String id) {
        inventoryDao.deleteInventory(id);
    }

    @Override
    public ImportResp batchAddInventory(List<Inventory> dataList) {
        List<Map> failedList = new ArrayList<>();
        int sort = 1;
        for (Inventory inventory : dataList) {
            Inventory oldInventory = inventoryDao.selectOneByParam(inventory.getSn(),
                    inventory.getPurchaseTime());
            if (!ObjectUtils.isEmpty(oldInventory)) {
                Map map = ObjectUtils.object2Map(inventory);
                map.put("sort", sort);
                map.put("message", "已存在库存记录");
                sort++;
                failedList.add(map);
                continue;
            }
            inventory.setId(SnowFlake.nextIdStr());
            inventory.setStatus(InventoryStatusEnum.NORMAL.getValue());
            inventory.setLeftNumber(inventory.getPurchaseNumber());
            inventoryDao.insert(inventory);
        }
        ImportResp resp = new ImportResp();
        resp.setFailedList(failedList);
        resp.setRetCode(failedList.size() > 0 ?
                ReturnCodes.HTTP_IMPORT_PART_FAIL.getRetCode() : ReturnCodes.HTTP_SUCCESS.getRetCode());
        resp.setRetMessage("导入库存信息成功");
        return resp;
    }

    @Override
    public void exportInventoryInfo(Map<String, Object> queryParam, HttpServletResponse response) {
        ExcelData data = new ExcelData();
        data.setFileName("库存信息导出excel.xlsx");
        List<Inventory> inventoryList = inventoryDao.getInventoryList(queryParam);
        String[] head = {"序号", "编号", "名称", "采购数量", "剩余数量", "采购时间", "过期时间"};
        data.setHead(head);
        String[][] dataList = new String[inventoryList.size()][head.length];
        int index = 0;
        for (Inventory item : inventoryList) {
            dataList[index][0] = String.valueOf(index + 1);
            dataList[index][1] = item.getSn();
            dataList[index][2] = item.getName();
            dataList[index][3] = String.valueOf(item.getPurchaseNumber());
            dataList[index][4] = String.valueOf(item.getLeftNumber());
            dataList[index][5] = item.getPurchaseTime();
            dataList[index][6] = item.getExpireTime();
            index++;
        }
        data.setData(Arrays.asList(dataList));
        ExcelUtils.exportExcel(response, data);
    }

    @Override
    public void clearInventory(String id) {
        //todo
    }

    @Override
    public void batchClearInventory(String id) {
        List<String> idList = Arrays.asList(id.split(","));
        inventoryDao.batchUpdateLeftNum(idList);
    }

    @Override
    public ImportResp importInventory(String fileName) {
        String filePath = fileName;
        return excelImportService.excelFile(filePath, 2, new ExcelImportCallBack() {
            @Override
            public Collection<RowError> checkRow(String[] record) {
                return checkRecordValid(record);
            }

            @Override
            public boolean persistRowToDb(String[] record) {
                Inventory inventory = covertToBean(record);
                return false;
//				try {
//					UserInventoryDao.addDetail(UserInventory);
//					return true;
//				} catch (Exception e) {
//					return false;
//				}
            }

            @Override
            public ImportResp partFailure(ImportResp resp) {
                resp.setRetMessage("导入库存数据部分失败，总数=" + resp.getTotal() + ",失败总数=" + resp.getFailedTotal());
                return resp;
            }

            @Override
            public ImportResp allSuccess(ImportResp resp) {
                resp.setRetMessage("导入库存数据全部成功，总数=" + resp.getTotal());
                return resp;
            }

            @Override
            public List<Map> convertFailList(List<String[]> failRecords) {
                List<Map> list = new ArrayList<>();
                int sort = 1;
                for (String[] failRecord : failRecords) {
                    Map item = new HashMap<>();
                    item.put("sort", sort);
                    item.put("sn", failRecord[0]);
                    item.put("name", failRecord[1]);
                    item.put("purchaseNumber", failRecord[2]);
                    item.put("purchaseTime", failRecord[3]);
                    list.add(item);
                    sort++;
                }
                return list;
            }

        });
    }

    /**
     * 转换数据为入库数据
     *
     * @param record 数据记录
     * @return 入库数据
     */
    private Inventory covertToBean(String[] record) {
        Inventory inventory = new Inventory();
        inventory.setSn(record[0].trim());
        inventory.setName(record[1].trim());
        inventory.setPurchaseNumber(Integer.parseInt(record[2].trim()));
        inventory.setPurchaseTime(record[3].trim());
        return inventory;

    }

    /**
     * 校验参数合法性
     *
     * @param record 导入数据
     * @return 参数合法性
     */
    private Collection<RowError> checkRecordValid(String[] record) {
        List<RowError> rowErrors = new ArrayList<>();
        if (StringUtils.isEmpty(record[0].trim())) {
            addRowError("编号不能为空", rowErrors);
        } else {
            if (record[0].trim().length() > 20) {
                addRowError("编号长度不能超过20", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[1].trim())) {
            addRowError("名称不能为空", rowErrors);
        } else {
            if (record[1].trim().length() > 200) {
                addRowError("编号长度不能超过200", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[2].trim())) {
            addRowError("采购数量不能为空", rowErrors);
        } else {
            if (record[2].trim().length() > 11) {
                addRowError("采购数量长度不能超过11", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[3].trim())) {
            addRowError("下单时间不能为空", rowErrors);
        } else {
            if (record[3].trim().length() > 11) {
                addRowError("下单时间格式非法", rowErrors);
            }
        }

        return rowErrors;
    }

    /**
     * 添加错误行数据
     *
     * @param errorMessage 错误信息
     * @param rowErrors    错误行数据
     */
    private void addRowError(String errorMessage, List<RowError> rowErrors) {
        RowError rowError = new RowError(errorMessage);
        rowErrors.add(rowError);
    }


}
